/**
 * 【注意】此文件已被新的指标计算系统替代
 * 请使用src/services/examples/indicator-app.ts作为新的入口点
 * 
 * 该文件保留仅用于向后兼容
 */

import * as fs from 'fs';
import * as path from 'path';
import { MarketDataService, KlineBar } from '../market-data.service';
import { BusinessService } from '../business';
import { IndicatorsService } from '../indicators.service';
// import { TradingLoggerService } from '../trading-logger.service';  // 不再使用完整的交易日志服务
import { KlineUtilsService } from '../kline-utils.service';
import { WebSocketManager, WebSocketType } from '../../core/ws-manager';
import { TAKlineData, RSIOptions } from '../../types/indicator.types';

interface RSICalculatorOptions {
  dataLimit: number;
  instId: string;
  rsiPeriod: number;
  enableRealtime: boolean;
  logDir?: string;
}

/**
 * 管理RSI值的滚动日志记录
 */
class RSILogger {
  private logFile: string = '';
  private chinaTimezoneOffset = 8 * 60 * 60 * 1000; // 中国时区偏移(毫秒)
  private recentRSIValues: Array<{ timestamp: number, rsi: number, price: number, updateTime: number }> = [];
  private maxEntries: number = 10;  // 保留最近10个周期
  private periodMs: number = 0;     // 周期时长(毫秒)

  /**
   * 初始化RSI日志记录器
   * @param instId 交易对
   * @param periodStr 周期字符串，如"1h"
   * @param logDir 日志目录
   */
  constructor(instId: string, periodStr: string, logDir?: string) {
    // 设置周期时长(毫秒)
    switch (periodStr) {
      case '1m': this.periodMs = 60 * 1000; break;
      case '3m': this.periodMs = 3 * 60 * 1000; break;
      case '5m': this.periodMs = 5 * 60 * 1000; break;
      case '15m': this.periodMs = 15 * 60 * 1000; break;
      case '30m': this.periodMs = 30 * 60 * 1000; break;
      case '1H': this.periodMs = 60 * 60 * 1000; break;
      case '4H': this.periodMs = 4 * 60 * 60 * 1000; break;
      case '1D': this.periodMs = 24 * 60 * 60 * 1000; break;
      default: this.periodMs = 60 * 60 * 1000; // 默认1小时
    }

    // 创建日志目录
    const logsDir = logDir || path.join(process.cwd(), 'logs');
    if (!fs.existsSync(logsDir)) {
      fs.mkdirSync(logsDir, { recursive: true });
    }

    // 创建日志文件，格式为RSI_周期.log，例如RSI_1h.log
    const cleanPeriod = periodStr.replace('H', 'h');
    this.logFile = path.join(logsDir, `RSI_${cleanPeriod}_${instId.replace(/-/g, '_')}.log`);
  }

  /**
   * 初始化日志内容，写入最近的10个RSI值
   * @param initialRSIValues 初始RSI值数组
   * @param prices 价格映射对象
   */
  initializeLog(initialRSIValues: { timestamp: string | number, value: number }[], prices: Record<number, number>): void {
    // 确保只保留最新的10个条目
    const recentValues = initialRSIValues.slice(-this.maxEntries);

    // 将RSI值转换为所需格式并记录
    this.recentRSIValues = recentValues.map(item => {
      const timestamp = typeof item.timestamp === 'string' ? parseInt(item.timestamp) : item.timestamp;
      return {
        timestamp,  // 原始K线周期时间戳
        rsi: item.value,
        price: prices[timestamp] || 0,
        updateTime: Date.now()  // 添加更新时间字段
      };
    });

    // 写入日志文件
    this.writeLogFile();
  }

  /**
   * 更新RSI值（实时数据更新）
   * @param timestamp 原始K线周期时间戳
   * @param rsi RSI值
   * @param price 收盘价
   */
  updateRSI(timestamp: number, rsi: number, price: number): void {
    // 获取当前系统时间作为更新时间
    const currentUpdateTime = Date.now();

    // 检查是否是最新的条目
    if (this.recentRSIValues.length > 0) {
      const lastItem = this.recentRSIValues[this.recentRSIValues.length - 1];

      // 检查是否是新周期，根据原始周期时间戳判断
      const isNewPeriod = timestamp - lastItem.timestamp >= this.periodMs;

      if (isNewPeriod) {
        // 如果已达到最大记录数，删除最旧的记录
        if (this.recentRSIValues.length >= this.maxEntries) {
          this.recentRSIValues.shift();
        }

        // 添加新的周期记录，使用当前系统时间作为更新时间
        this.recentRSIValues.push({
          timestamp,        // 原始K线周期时间戳
          rsi,
          price,
          updateTime: currentUpdateTime  // 当前系统时间
        });
      } else {
        // 更新最新条目，只更新RSI、价格和更新时间，保持原始周期时间戳不变
        this.recentRSIValues[this.recentRSIValues.length - 1] = {
          timestamp: lastItem.timestamp,  // 保持原始周期时间戳不变
          rsi,
          price,
          updateTime: currentUpdateTime   // 使用最新系统时间
        };
      }
    } else {
      // 如果数组为空，直接添加
      this.recentRSIValues.push({
        timestamp,
        rsi,
        price,
        updateTime: currentUpdateTime
      });
    }

    // 更新日志文件
    this.writeLogFile();
  }

  /**
   * 写入日志文件
   */
  private writeLogFile(): void {
    const content = this.formatLogContent();
    fs.writeFileSync(this.logFile, content);
  }

  /**
   * 格式化日志内容
   */
  private formatLogContent(): string {
    // 按原始周期时间戳排序
    const sortedValues = [...this.recentRSIValues].sort((a, b) => a.timestamp - b.timestamp);

    // 生成日志内容
    let content = '时间戳(北京时间),收盘价,RSI值\n';
    content += sortedValues.map(item => {
      // 对于最新的条目，使用更新时间而不是周期时间戳
      const isLatestItem = item === sortedValues[sortedValues.length - 1];
      const timeToFormat = isLatestItem ? item.updateTime : item.timestamp;

      const chinaTime = this.formatChinaTime(timeToFormat);
      return `${chinaTime}, ${item.price}, ${item.rsi.toFixed(2)}`;
    }).join('\n');

    return content;
  }

  /**
   * 获取中国时区的格式化时间，去除毫秒和时区信息
   */
  formatChinaTime(timestamp: number): string {
    const chinaDate = new Date(timestamp + this.chinaTimezoneOffset);
    // 格式化为 YYYY-MM-DDTHH:MM:SS 格式，去掉毫秒和时区
    return chinaDate.toISOString().replace('Z', '').split('.')[0];
  }
}

async function runOptimizedRSICalculator(options: RSICalculatorOptions): Promise<void> {
  console.log('📊 启动优化版RSI计算器...');
  console.log(`交易对: ${options.instId}`);
  console.log(`RSI周期: ${options.rsiPeriod}`);
  console.log(`数据限制: ${options.dataLimit}条`);
  console.log(`实时更新: ${options.enableRealtime ? '启用' : '禁用'}`);

  try {
    // 初始化服务
    const marketDataService = new MarketDataService('https://www.okx.com', {
      proxy: 'socks5://192.168.31.174:7890',
      timeout: 30000
    });
    const indicatorsService = new IndicatorsService();
    const klineUtils = new KlineUtilsService();

    // 测试API连接
    console.log('测试与OKX API的连接...');
    const connectionTest = await marketDataService.testConnection();
    if (!connectionTest.success) {
      throw new Error(`连接测试失败: ${connectionTest.message}`);
    }
    console.log('连接测试成功!');

    // 获取历史数据
    console.log('\n===== 获取历史K线数据 =====');
    const params = {
      instId: options.instId,
      bar: KlineBar.HOUR_1,
      limit: 300
    };

    // 获取历史K线数据
    const rawKlines = await marketDataService.getAllHistoricalKlines(params, options.dataLimit);
    console.log(`总共获取了 ${rawKlines.length} 条K线数据`);

    // 格式化数据
    const formattedKlines = rawKlines.map(kline => ({
      timestamp: parseInt(kline[0]),
      open: parseFloat(kline[1]),
      high: parseFloat(kline[2]),
      low: parseFloat(kline[3]),
      close: parseFloat(kline[4]),
      volume: parseFloat(kline[5]),
      volumeCcy: parseFloat(kline[6]),
      volumeCcyQuote: parseFloat(kline[7]),
      confirmed: kline[8] === '1'
    }));

    // 按时间从旧到新排序
    formattedKlines.sort((a, b) => a.timestamp - b.timestamp);

    // 转换为技术指标格式
    const taKlines = klineUtils.convertFormattedToTA(formattedKlines);

    // 计算RSI
    console.log('\n===== 计算RSI值 =====');
    const rsiResults = indicatorsService.calculateRSI(taKlines, { period: options.rsiPeriod });
    console.log(`成功计算出 ${rsiResults.length} 个RSI值`);

    // 创建价格映射
    const priceMap = klineUtils.createPriceMap(taKlines);

    // 初始化RSI日志记录器 (使用1H作为周期)
    const rsiLogger = new RSILogger(options.instId, '1H', options.logDir);

    // 初始化日志，写入最近10个周期的RSI值
    rsiLogger.initializeLog(rsiResults, priceMap);
    console.log(`日志文件已初始化，记录了最近10个周期的RSI值`);

    // 分析并输出结果
    if (rsiResults.length > 0) {
      // 获取统计数据
      const stats = indicatorsService.analyzeRSIStatistics(rsiResults);

      // 分析最新RSI
      const latestRsi = rsiResults[rsiResults.length - 1];
      const analysis = indicatorsService.analyzeRSI(latestRsi.value);

      console.log('\n===== RSI计算结果摘要 =====');
      console.log(`\n最新RSI值: ${latestRsi.value.toFixed(2)} (${analysis.status})`);
      console.log(analysis.message);

      console.log('\nRSI统计分析:');
      console.log(`最小值: ${stats.min.toFixed(2)}`);
      console.log(`最大值: ${stats.max.toFixed(2)}`);
      console.log(`平均值: ${stats.avg.toFixed(2)}`);
      console.log(`超买次数: ${stats.overboughtCount} (${stats.overboughtPercentage.toFixed(2)}%)`);
      console.log(`超卖次数: ${stats.oversoldCount} (${stats.oversoldPercentage.toFixed(2)}%)`);
    }

    // 启用实时更新
    if (options.enableRealtime) {
      console.log('\n===== 启动实时K线订阅和RSI更新 =====');

      // 初始化WebSocket连接
      const wsManager = new WebSocketManager();
      const businessClient = wsManager.getClient(WebSocketType.BUSINESS);
      await businessClient.connect();
      console.log('✅ WebSocket连接成功');

      // 创建业务服务实例
      const businessService = new BusinessService(businessClient);

      // 根据REST API的K线周期获取对应的WebSocket订阅周期
      const candlePeriod = klineUtils.convertToWebSocketPeriod(KlineBar.HOUR_1);

      // 保存当前K线数据副本用于实时更新
      let realtimeTaKlines = [...taKlines];

      console.log(`正在订阅 ${options.instId} 的 ${candlePeriod} 周期K线数据...`);

      // 使用business.ts的subscribeCandle方法订阅K线数据
      await businessService.subscribeCandle(
        candlePeriod,
        options.instId,
        (candleData) => {
          if (candleData && candleData.length > 0) {
            // 使用工具服务转换K线格式
            const newKline = klineUtils.convertWebSocketToTA(candleData[0]);
            const timestamp = newKline.timestamp as number;

            console.log(`\n📊 收到K线更新: ${rsiLogger.formatChinaTime(timestamp)}`);

            // 更新K线数据数组
            realtimeTaKlines = klineUtils.updateKlines(
              realtimeTaKlines,
              newKline,
              options.dataLimit
            );

            // 重新计算RSI
            const updatedRsiResults = indicatorsService.calculateRSI(
              realtimeTaKlines,
              { period: options.rsiPeriod }
            );

            if (updatedRsiResults.length > 0) {
              const newLatestRsi = updatedRsiResults[updatedRsiResults.length - 1];
              const rsiTimestamp = typeof newLatestRsi.timestamp === 'string' ?
                parseInt(newLatestRsi.timestamp) : newLatestRsi.timestamp;

              // 分析新RSI值
              const analysis = indicatorsService.analyzeRSI(newLatestRsi.value);

              // 更新RSI日志
              rsiLogger.updateRSI(rsiTimestamp, newLatestRsi.value, newKline.close);

              // 打印分析结果
              console.log(`时间: ${rsiLogger.formatChinaTime(Date.now())}`);
              console.log(`价格: ${newKline.close} (开:${newKline.open} 高:${newKline.high} 低:${newKline.low})`);
              console.log(`RSI: ${newLatestRsi.value.toFixed(2)} (${analysis.status})`);
              console.log(analysis.message);
            }
          }
        },
        30000 // 30秒超时
      );

      console.log(`✅ 成功订阅${options.instId}的${candlePeriod}周期K线数据`);
      console.log('📊 现在将持续接收实时K线数据并更新RSI值');

      // 设置优雅退出
      process.on('SIGINT', async () => {
        console.log('🛑 正在取消订阅并关闭连接...');
        try {
          await businessService.unsubscribeCandle(candlePeriod, options.instId);
          wsManager.closeAll();
        } catch (err) {
          console.error('取消订阅出错:', err);
        }
        console.log('👋 已完成清理，退出程序');
        process.exit(0);
      });

      console.log('输入Ctrl+C终止程序...');
    }

  } catch (error: any) {
    console.error('❌ RSI计算器运行失败:', error.message || error);
  }
}

/**
 * 解析命令行参数
 * @returns RSI计算器配置项
 */
function parseCommandLineArgs(): RSICalculatorOptions {
  const args = process.argv.slice(2);

  const options: RSICalculatorOptions = {
    dataLimit: 5000,
    instId: 'ETH-USDT-SWAP',
    rsiPeriod: 6,
    enableRealtime: true
  };

  for (let i = 0; i < args.length; i++) {
    if (args[i] === '--limit' && i + 1 < args.length) {
      options.dataLimit = parseInt(args[i + 1]);
    } else if (args[i] === '--instId' && i + 1 < args.length) {
      options.instId = args[i + 1];
    } else if (args[i] === '--period' && i + 1 < args.length) {
      options.rsiPeriod = parseInt(args[i + 1]);
    } else if (args[i] === '--realtime') {
      options.enableRealtime = true;
    }
  }

  return options;
}

// 入口函数
function main() {
  const options = parseCommandLineArgs();
  runOptimizedRSICalculator(options)
    .catch(err => console.error('程序执行出错:', err));
}

// 如果直接运行此文件，则执行main函数
if (require.main === module) {
  main();
}

// 导出选项和主函数
export { runOptimizedRSICalculator, RSICalculatorOptions };